package ro.dandanciu.webgallery.services.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Transactional;

import ro.dandanciu.webgallery.constants.GalleriesConstants;
import ro.dandanciu.webgallery.domainmodel.Gallery;
import ro.dandanciu.webgallery.domainmodel.Image;
import ro.dandanciu.webgallery.exceptions.ApplicationException;
import ro.dandanciu.webgallery.services.ImageServices;

@Transactional
public class ImageServicesImpl implements ImageServices {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger
			.getLogger(ImageServicesImpl.class);

	private EntityManager em;

	@PersistenceContext
	public void setEntityManager(EntityManager em) {
		this.em = em;
	}
	
	public void add(File imageFile, Gallery parent, String name, String contentType) {
		if (logger.isDebugEnabled()) { 
			logger.debug("add(File, Gallery) - start");
		}

		Image image = new Image();
		image.setName(name);
		image.setSize(imageFile.length());
		image.setContentType(contentType);
		image.setParent(parent);
		image.setUpdater(parent.getOwner().getUserId());
		em.persist(image);
		
		
		Gallery tempParent = parent;
		String path = (File.separator + parent.getOwner().getUserId());
		while(tempParent != null) {
			path = path + (File.separator + tempParent.getName().trim());
			tempParent = tempParent.getParent();
		}
		path = GalleriesConstants.GALLERIES_BASE_DIRECTORY + path;
		File file = new File(path);
		if (!file.exists()) {
			file.mkdirs();
		}
		

		try {
			copyFileToDirectory(file, imageFile, name);
		} catch (IOException e) {
			logger.error(e);
			throw new ApplicationException(e);  
		}

		if (logger.isDebugEnabled()) {
			logger.debug("add(File, Gallery) - end");
		}
	}
	
	private void copyFileToDirectory(File whereToCopy, File src, String name) throws IOException {
		File dst = new File(whereToCopy, name);
        InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dst);
    
        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();
	}
	
	@SuppressWarnings("unchecked")
	public List<Image> getImagesForGallery(Gallery gallery) {
		Query query = em.createNamedQuery("Image.GetByGalleryId");
		query.setParameter("galleryId", gallery.getId());
		return (List<Image>) query.getResultList();
	}

	public void delete(long galleryId, String fileName) {
		Query query = em.createNamedQuery("Image.DeleteByGalleryIdAndFileName");
		query.setParameter("galleryId", galleryId);
		query.setParameter("name", fileName);
		query.executeUpdate();
		
	}

}
